home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / TERMINAL / SRCS / POPUP.C < prev    next >
Text File  |  1990-11-20  |  5KB  |  249 lines

  1. /*
  2.     Terminal 2.0
  3.     "Popup.c"
  4. */
  5.  
  6. #ifdef THINK_C
  7. #include "MacHeaders"
  8. #endif
  9. #ifdef applec
  10. #pragma load ":(Objects):MacHeadersMPW"
  11. #pragma segment Options
  12. #endif
  13.  
  14. #include "Popup.h"
  15.  
  16. static POPUP *Popup;    /* Current popup structure array */
  17.  
  18. #ifdef NEWPOPUP
  19. /* ----- Draw downward pointing triangle ------------------------------- */
  20.  
  21. /*        ***********
  22.          *********
  23.           *******
  24.            *****
  25.             ***
  26.         +    *
  27. */
  28.  
  29. #define SYMBOL_WIDTH 12
  30.  
  31. static void DrawTriangle(register short h, register short v)
  32. {
  33.     register short i;
  34.  
  35.     for (i = 0; i < 6; ++i)    {
  36.         MoveTo(h + 5 - i, v - i);
  37.         Line(2*i, 0);
  38.     }
  39. }
  40. #endif
  41.  
  42. /* ----- Find popup structure ------------------------------------------ */
  43.  
  44. static POPUP *FindPopup(
  45.         register short item)    /* Dialog item number */
  46. {
  47.     register POPUP *p = Popup;
  48.  
  49.     while (p->item) {
  50.             if (p->item == item)
  51.                 return p;        /* Here it is */
  52.             ++p;
  53.     }
  54.     return 0;                    /* Not found */
  55. }
  56.  
  57. /* ----- Draw popup box ------------------------------------------------ */
  58.  
  59. static pascal void DrawPopUp(    /* Called as user item in dialog */
  60.     register DialogPtr dialog,
  61.     register short item)
  62. {
  63.     register Byte text[256];
  64.     PenState savePen;
  65.     Rect box;
  66.     FontInfo info;
  67.  
  68.     GetPenState(&savePen);
  69.     GetFontInfo(&info);
  70.  
  71.     /* Get user item box. Reference point is top left. */
  72.     {
  73.         short type;
  74.         Handle hdl;
  75.  
  76.         GetDItem(dialog, item, &type, &hdl, &box);
  77.     }
  78.  
  79.     /* Get and draw menu title. Get item text. */
  80.     {
  81.         register POPUP *p = FindPopup(item);
  82.         register Byte *s;
  83.  
  84.         if (!p || !p->h)
  85.             return;
  86.         s = (**(p->h)).menuData;    /* Menu title */
  87.         MoveTo(box.left - StringWidth(s) - 2, box.top + info.ascent);
  88.         DrawString(s);
  89.         GetItem(p->h, p->choice, text);
  90.     }
  91.  
  92.     /* Adjust item text so it fits in the box. */
  93.     {
  94.         register short wid = (box.right - box.left) -
  95.             (CharWidth(checkMark) + 2);
  96.         register short newWid = StringWidth(text);
  97.  
  98.         if (newWid > wid) {
  99.             wid -= CharWidth('╔');
  100.             do {
  101.                 newWid -= CharWidth(text[text[0]]);
  102.                 --text[0];
  103.             } while (newWid > wid && text[0]);
  104.             ++text[0];
  105.             text[text[0]] = '╔';
  106.         }
  107.     }
  108.  
  109.     /* Draw item text. */
  110.     MoveTo(box.left + CharWidth(checkMark) + 2, box.top + info.ascent);
  111.     DrawString(text);
  112.  
  113. #ifdef NEWPOPUP
  114.     /* Draw downward pointing arrow */
  115.     DrawTriangle(box.right - SYMBOL_WIDTH - 2, box.top + info.ascent);
  116. #endif
  117.  
  118.     /* Draw box with dropping shadow. */
  119.     InsetRect(&box, -1, -1);
  120.     PenSize(1, 1);
  121.     FrameRect(&box);
  122.     MoveTo(box.left + 2, box.bottom);
  123.     LineTo(box.right, box.bottom);
  124.     LineTo(box.right, box.top + 2);
  125.  
  126.     SetPenState(&savePen);
  127. }
  128.  
  129. /* ----- Handle MouseDown ---------------------------------------------- */
  130.  
  131. Boolean PopupMousedown(                /* Called from dialog filter */
  132.     register DialogPtr dialog,
  133.     register EventRecord *event,
  134.     register short *i)
  135. {
  136.     register short item;
  137.     register POPUP *p;
  138.     Point loc;
  139.     short choice;
  140.     long chosen;
  141.     short type;
  142.     Handle hdl;
  143.     Rect box, title;
  144.     Boolean result = FALSE;
  145.  
  146.     /* Find dialog item where mouse click is in */
  147.  
  148.     loc = event->where;
  149.     GlobalToLocal(&loc);
  150.     if ((item = FindDItem(dialog, loc) + 1) < 1)
  151.         return result;
  152.     p = FindPopup(item);
  153.     if (!p || !p->h)
  154.         return result;
  155.  
  156.     /* Coordinate calculations */
  157.  
  158.     GetDItem(dialog, item, &type, &hdl, &box);
  159.     loc = topLeft(box);
  160.     LocalToGlobal(&loc);
  161.     title = box;
  162.     title.right = box.left - 1;
  163.     title.left = title.right - StringWidth((**(p->h)).menuData) - 2;
  164.     box.top -= 1;
  165.     box.left -= 1;
  166.     box.bottom += 2;
  167.     box.right += 2;
  168.  
  169.     /* Erase popup box and invert title */
  170.  
  171.     EraseRect(&box);
  172.     InvertRect(&title);
  173.  
  174.     /* Pop the menu up */
  175.  
  176.     InsertMenu(p->h, hierMenu);
  177.     SetItemMark(p->h, p->choice, checkMark);
  178.     CalcMenuSize(p->h);        /* Menu Mgr bug */
  179.     chosen = PopUpMenuSelect(p->h, loc.v, loc.h, p->choice);
  180.     SetItemMark(p->h, p->choice, noMark);
  181.     DeleteMenu(p->menu);
  182.  
  183.     /* Get choice from popup menu */
  184.  
  185.     if (chosen) {
  186.         choice = chosen & 0xFFFF;
  187.         if (choice != p->choice) {    /* New choice */
  188.             p->choice = choice;
  189.             *i = item;
  190.             result = TRUE;
  191.         }
  192.     }
  193.  
  194.     /* Redraw popup box */
  195.  
  196.     InvertRect(&title);
  197.     DrawPopUp(dialog, item);
  198.  
  199.     return result;
  200. }
  201.  
  202. /* ----- Init popup menus in dialog ------------------------------------ */
  203.  
  204. void PopupInit(
  205.     register DialogPtr dialog,
  206.     POPUP *popups)
  207. {
  208.     register POPUP *p;
  209.     register short w;
  210.     FontInfo info;
  211.     short type;
  212.     Handle hdl;
  213.     Rect box;
  214.  
  215.     Popup = p = popups;
  216.     SetPort(dialog);
  217.     GetFontInfo(&info);
  218.     while (p->item) {
  219.         if (p->h = GetMenu(p->menu)) {
  220.             /* Correct user item box. */
  221.             GetDItem(dialog, p->item, &type, &hdl, &box);
  222.             CalcMenuSize(p->h);
  223.             w = (**(p->h)).menuWidth;
  224. #ifdef NEWPOPUP
  225.             w += SYMBOL_WIDTH + 2;
  226. #endif
  227.             if (w < (box.right - box.left))
  228.                 box.right = box.left + w;
  229.             box.bottom = box.top +
  230.                 info.ascent + info.descent + info.leading;
  231.             SetDItem(dialog, p->item, type, (Handle)DrawPopUp, &box);
  232.         }
  233.         ++p;
  234.     }
  235. }
  236.  
  237. /* ---- Get rid of popup menus ----------------------------------------- */
  238.  
  239. void PopupCleanup(void)
  240. {
  241.     register POPUP *p = Popup;
  242.  
  243.     while (p->item) {
  244.         if (p->h)
  245.             ReleaseResource((Handle)p->h);
  246.         ++p;
  247.     }
  248. }
  249.